package com.chenyue.cm.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chenyue.cm.common.constant.RedisPrefix;
import com.chenyue.cm.common.utils.StringUtils;
import com.chenyue.cm.live.vo.LiveUserRedis;
import com.chenyue.cm.user.dao.JdAppUserMapper;
import com.chenyue.cm.user.domain.JdAppUser;
import com.chenyue.cm.utils.im.util.ImConfig;
import com.chenyue.cm.utils.im.util.TLSSigAPIv2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * redis 缓存工具类
 *
 * @author LBX
 */
@Service
public class RedisUtils {

    private final RedisTemplate<String, Object> redisTemplate;

    private final ValueOperations<String, Object> valueOperations;

    private final JdAppUserMapper userMapper;

    private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);

    // 不设置过期时间
    private final static long NOT_EXPIRE = -1;

    public RedisUtils(RedisTemplate<String, Object> redisTemplate, ValueOperations<String, Object> valueOperations, @Qualifier("jdAppUserMapper") JdAppUserMapper userMapper) {
        this.redisTemplate = redisTemplate;
        this.valueOperations = valueOperations;
        this.userMapper = userMapper;
    }

    public long getExpire(String key) {
        return redisTemplate.opsForValue().getOperations().getExpire(key);
    }

    public void setToken(Integer userId, String token) {
        String key = RedisPrefix.LOGIN_USER_TOKEN + userId;
        redisTemplate.opsForValue().set(key, token, 15, TimeUnit.DAYS);
    }

    public String getToken(String userId) {
        String key = RedisPrefix.LOGIN_USER_TOKEN + userId;
        return (String) redisTemplate.opsForValue().get(key);
    }

    public void deleteToken(String userId) {
        String key = RedisPrefix.LOGIN_USER_TOKEN + userId;
        redisTemplate.delete(key);
    }

    /**
     * @param expire 过期时间 单位：秒
     */
    public void set(String key, Object value, long expire) {
        valueOperations.set(key, value);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    public void set(String key, Object value) {
        set(key, value, 300);
    }

    public <T> T get(String key, Class<T> clazz, long expire) {
        Object value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        if (value != null) {
            if (clazz.isInstance(value)) {
                return clazz.cast(value);
            }
        }
        return null;
    }

    public <T> T get(String key, Class<T> clazz) {
        return get(key, clazz, NOT_EXPIRE);
    }

    public String get(String key, long expire) {
        Object value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value == null ? null : value.toString();
    }

    public String get(String key) {
        return get(key, NOT_EXPIRE);
    }

    public void delete(String key) {
        redisTemplate.delete(key);
    }

    private boolean hasKey(String key) {
        return this.redisTemplate.hasKey(key);
    }

    public Object getRedis(String key) {
        //先获取缓存中的
        return redisTemplate.opsForValue().get(key);
    }

    //更新用户缓存
    public void updateUser(JdAppUser user) {
        //存入redis
        valueOperations.set(RedisPrefix.LOGIN_USER + user.getId(), user);
        redisTemplate.expire(RedisPrefix.LOGIN_USER + user.getId(), 15, TimeUnit.DAYS);
    }

    public void submitLock(Integer id) {
        String key = "SUBMIT_LOCK_" + id;
        redisTemplate.opsForValue().set(key, id, 1, TimeUnit.MINUTES);
    }

    public String getSubmitLock(Integer id) {
        String key = "SUBMIT_LOCK_" + id;
        return redisTemplate.opsForValue().get(key) == null ? "" : redisTemplate.opsForValue().get(key) + "";
    }

    public void deleteSubmitLock(Integer id) {
        String key = "SUBMIT_LOCK_" + id;
        redisTemplate.delete(key);
    }

    public String getImUserSign() {
        String key = "FITNESS.IM.USER.SIGN";
        if (redisTemplate.opsForValue().get(key) != null) {
            return redisTemplate.opsForValue().get(key) + "";
        } else {
            TLSSigAPIv2 sign = new TLSSigAPIv2(ImConfig.SDK_APP_ID, ImConfig.SECRET_KEY);
            String userSign = sign.genSig(ImConfig.IDENTIFY, 604800);
            redisTemplate.opsForValue().set(key, userSign, 604800, TimeUnit.SECONDS);
            return userSign;
        }
    }

    /**
     * 获取小程序 AccessToken
     */
    public String getAccessToken() throws IOException {
        String key = "SMALL_UN_LIMITED_ACCESS_TOKEN";
        if (hasKey(key)) {
            return get(key);
        }
        String appId = "wx8bce7b3b1202581d&secret=7483202c0f5e2aecee8f221af04de6e3";
        String appSecret = "7483202c0f5e2aecee8f221af04de6e3";
        String grantType = "client_credential";
        String result = OkHttpUtils.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grantType + "&appid=" + appId + "&secret=" + appSecret);
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.getInteger("errcode") == null) {
            String accessToken = jsonObject.getString("access_token");
            Integer expiresIn = jsonObject.getInteger("expires_in");
            set(key, accessToken, expiresIn);
            return accessToken;
        } else {
            System.err.println(jsonObject.getInteger("errcode"));
            System.err.println(jsonObject.getInteger("errmsg"));
        }
        return null;
    }

    /**
     * 根据指令操作连麦人
     *
     * @param content   内容
     * @param operation 操作指令 1新增 2删除 3全部除 4编辑
     */
    public void operationLiveUser(LiveUserRedis content, int operation) {
        try {
            String key = RedisPrefix.LIVE_USER + content.getRecordId();
            final String s = get(key);
            List<LiveUserRedis> idList;
            logger.info("===========" + s);
            if (StringUtils.isNotBlank(s) && !"null".equals(s)) {
                idList = JSON.parseArray(s, LiveUserRedis.class);
            } else {
                idList = new ArrayList<>();
            }
            switch (operation) {
                case 1:
    //                1新增
                    idList.add(content);
                    break;
                case 2:
    //                2删除
                    idList = idList.stream().filter(id -> !id.getUserId().equals(content.getUserId())).collect(Collectors.toList());
                    break;
                case 3:
    //                3全部删除
                    delete(key);
                    return;
                case 4:
    //                4编辑
                    for (LiveUserRedis userRedis : idList) {
                        if (userRedis.getUserId().equals(content.getUserId())) {
                            userRedis.setStartTime(System.currentTimeMillis() / 1000);
                            break;
                        }
                    }
                    break;
                default:
                    break;
            }
            set(key, JSON.toJSONString(idList));
        } catch (Exception e) {
            logger.info("========连麦人操作异常=========");
            System.err.println(e);
        }
    }
}


